import numpy as np
import scipy


def is_positive_definite(matrix):
    """
    利用特征值判断矩阵是否正定
    """
    # 计算矩阵的特征值
    eigenvalues = np.linalg.eigvals(matrix)
    return np.all(eigenvalues > 0)


def is_positive_definite_det(matrix):
    """
    利用顺序主子式判断矩阵正定
    """
    # 获取矩阵的行数
    n = matrix.shape[0]

    for i in range(1, n + 1):
        # 判断顺序子矩阵的行列式值
        if np.linalg.det(matrix[:i, :i]) <= 0:
            return False
    return True


def is_positive_definite_element(A):
    # # 检查对称性
    # if not np.allclose(A, A.T):
    #     return False

    try:
        # LU分解获取主元
        _, U = scipy.linalg.lu(A, permute_l=True)
        pivots = np.diag(U)
        return np.all(pivots > 0)
    except:
        return False


def is_positive_definite_cholesky(matrix):
    try:
        np.linalg.cholesky(matrix)
        return True
    except np.linalg.LinAlgError:
        return False


if __name__ == '__main__':
    matrix = np.array([
        [1, 5],
        [0, 6]
    ])

    print(is_positive_definite(matrix))

    print(is_positive_definite_det(matrix))

    print(is_positive_definite_element(matrix))
    print(is_positive_definite_det(matrix))